home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / wasm223.zip / TABS.ASM < prev    next >
Assembly Source File  |  1993-05-05  |  16KB  |  490 lines

  1. ;================================================
  2. ; TABS By Eric Tauck
  3. ;
  4. ; This program optimally compresses all spaces to
  5. ; tab characters or expands all tab characters to
  6. ; spaces.  Additionally, spaces and tabs are
  7. ; removed from the end of lines and blank lines
  8. ; are removed from the end of files.  These func-
  9. ; tions are useful for cleaning up and compres-
  10. ; sing source files (especially assembler files).
  11. ;
  12. ; The usage is:
  13. ;
  14. ;   TABS source [target] [/C] [/X]
  15. ;
  16. ; If 'target' is not present, a temporary file
  17. ; ('source.$$$') becomes the target and is later
  18. ; renamed to 'source' after deleting 'source'.
  19. ; /C specifies compression to tabs (this is the
  20. ; default).  /X specifies expansion to spaces.
  21. ; Note that tabs are fixed at every 8 spaces.
  22. ;
  23. ; This program uses the WASM library files.
  24.  
  25.         JUMP+           ;let's optimize jumps
  26.  
  27. ;--- library files
  28.  
  29.         INCLUDE 'library\start'
  30.         INCLUDE 'library\buffer1'
  31.         INCLUDE 'library\buffer2'
  32.         INCLUDE 'library\buffer3'
  33.         INCLUDE 'library\case1'
  34.         INCLUDE 'library\case2'
  35.         INCLUDE 'library\string'
  36.         INCLUDE 'library\file'
  37.         INCLUDE 'library\memory'
  38.         INCLUDE 'library\message1'
  39.         INCLUDE 'library\parms'
  40.  
  41. ;--- a few equates
  42.  
  43. BUFSIZE EQU     50000   ;read and write buffer sizes
  44.  
  45. TAB     EQU     9       ;tab
  46. LF      EQU     10      ;linefeed
  47. CR      EQU     13      ;carriage return
  48. EOF     EQU     26      ;end of file marker
  49.  
  50. ;--- program entry point
  51.  
  52.         mov     ax, OFFSET banner       ;banner address
  53.         call    MesPutL                 ;display
  54.  
  55. ;=== set up parameters
  56.  
  57.         mov     di, 1                   ;initial parameter number
  58.  
  59. main1   call    ParGet                  ;get parameter
  60.         jc      main6                   ;jump if no more
  61.         mov     si, ax                  ;save in SI
  62.         call    StrUpr                  ;convert to uppercase
  63.  
  64. ;--- check if expand option
  65.  
  66.         mov     ax, si
  67.         mov     bx, OFFSET opt_exp      ;option string
  68.         call    StrCmp                  ;check if option
  69.         jc      main2                   ;jump if not
  70.         or      flags, NO_COMP          ;set flag
  71.         jmps    main1
  72.  
  73. ;--- check if compress option
  74.  
  75. main2   mov     ax, si
  76.         mov     bx, OFFSET opt_com      ;option string
  77.         call    StrCmp                  ;check if option
  78.         jc      main3                   ;jump if not
  79.         and     flags, NOT NO_COMP      ;clear flag
  80.         jmps    main1
  81.  
  82. ;--- check if source name
  83.  
  84. main3   cmp     di, 1                   ;check if source
  85.         jne     main4                   ;jump if not
  86.         mov     srcname, si             ;save source name
  87.         inc     di
  88.         jmps    main1
  89.  
  90. ;--- check if destination name
  91.  
  92. main4   cmp     di, 2                   ;check if destination
  93.         jnz     main5                   ;jump if not
  94.         mov     desname, si             ;save destination name
  95.         inc     di
  96.         jmps    main1
  97.  
  98. ;--- incorrect parameters
  99.  
  100. main5   mov     ax, OFFSET help         ;help message
  101.         sub     bp, bp                  ;no file name
  102.         jmp     error2                  ;branch to error
  103.  
  104. ;--- check file names, maybe create temporary file
  105. ;
  106. ;    NOTE: this will not work correctly if the source file contains a
  107. ;    short filespec with a directory containing an extension, for
  108. ;    example:  X.Y\A  -- will think .Y\A is extension.
  109.  
  110. main6   cmp     srcname, 0FFFFH ;check if no source
  111.         je      main5
  112.         cmp     desname, 0FFFFH ;check if no destination
  113.         jne     main9
  114.  
  115.         or      flags, DO_REN           ;set rename flag
  116.         mov     ax, srcname             ;source name
  117.         mov     bx, OFFSET desfnam      ;storage for destination name
  118.         mov     desname, bx             ;save address
  119.         push    bx                      ;save for later
  120.         call    StrCpy                  ;copy source name
  121.         pop     ax
  122.         mov     di, ax
  123.         call    Strlen                  ;get length
  124.         add     di, ax                  ;add point to end byte
  125.         mov     si, di                  ;save for adding ext if no dot
  126.         dec     di                      ;adjust to last byte
  127.         cmp     ax, 4                   ;check if 4 or less
  128.         jbe     main7                   ;jump if so
  129.         mov     ax, 4                   ;max 4 bytes to search
  130. main7   mov     cx, ax                  ;bytes to scan
  131.         mov     al, '.'                 ;look for dot
  132.         std
  133.         repne                           ;for length
  134.         scasb                           ;scan for dot
  135.         jne     main8                   ;jump if not found
  136.         mov     si, di                  ;source
  137.         inc     si                      ;point to dot
  138. main8   mov     ax, OFFSET exten        ;extension
  139.         mov     bx, si                  ;place to put it
  140.         call    StrCpy                  ;copy it
  141.  
  142. ;--- set up file records
  143.  
  144. main9   mov     si, OFFSET srcfile      ;source file record
  145.         mov     di, OFFSET desfile      ;destination file record
  146.  
  147.         mov     ax, BUFSIZE     ;bytes for buffer
  148.         mov     bx, si          ;file record
  149.         call    BufAll          ;allocate buffer
  150.         jc      mainC           ;jump if error
  151.  
  152.         mov     ax, BUFSIZE     ;bytes for buffer
  153.         mov     bx, di          ;file record
  154.         call    BufAll          ;allocate buffer
  155.         jnc     mainA           ;jump if okay
  156.  
  157.         mov     bx, si
  158.         call    BufRel          ;release first buffer before error
  159.         jmps    mainC
  160.  
  161. ;=== process files
  162.  
  163. mainA   call    Open            ;open files
  164.         jc      mainD
  165.         call    Process         ;process files
  166.         jc      mainE
  167.         call    Close           ;close files
  168.         jc      mainE
  169.  
  170. ;--- finished
  171.  
  172.         mov     bx, di
  173.         call    BufRel          ;release buffer
  174.         mov     bx, si
  175.         call    BufRel          ;release buffer
  176.  
  177. ;--- delete and rename
  178.  
  179.         test    flags, DO_REN   ;check if rename
  180.         jz      mainB
  181.  
  182.         mov     ah, 41H         ;delete function
  183.         mov     dx, srcname     ;name of file
  184.         int     21H             ;execute
  185.  
  186.         mov     ah, 56H         ;rename function
  187.         mov     dx, desname     ;current name
  188.         mov     di, srcname     ;target name
  189.         int     21H             ;execute
  190.  
  191. ;--- terminate
  192.  
  193. mainB   mov     ax, 4C00H       ;terminate function
  194.         int     21H             ;execute
  195.  
  196. ;--- memory allocation error
  197.  
  198. mainC   mov     ax, OFFSET emess1
  199.         sub     bp, bp
  200.         jmps    error2
  201.  
  202. ;--- file open or creation error
  203.  
  204. mainD   mov     ax, OFFSET emess2
  205.         jmps    error1
  206.  
  207. ;--- file read or write error
  208.  
  209. mainE   mov     ax, OFFSET emess3
  210.  
  211. ;--- error message in AX, file name in BP
  212.  
  213. error1  push    ax
  214.         mov     bx, di
  215.         call    BufRel          ;release buffer
  216.         mov     bx, si
  217.         call    BufRel          ;release buffer
  218.         pop     ax
  219.  
  220. error2  or      bp, bp          ;check if file name
  221.         jz      error3          ;jump if not
  222.         call    MesPut          ;display message
  223.         mov     ax, bp
  224. error3  call    MesPutL         ;display file name / error message
  225.  
  226.         mov     ax, 4CFFH       ;exit with error code 256
  227.         int     21H             ;execute
  228.  
  229. ;========================================
  230. ; Open files.
  231. ;
  232. ; In: SI and DI= source and destination
  233. ;     buffer records.
  234. ;
  235. ; Out: CY= set if error; BP= name of file
  236. ;      if error.
  237.  
  238. Open    PROC    NEAR
  239.         mov     ax, srcname             ;source file
  240.         mov     bp, ax
  241.         mov     bx, si                  ;buffer record
  242.         mov     cl, BUFFER_READ         ;read
  243.         call    BufOpn                  ;open buffer
  244.         jc      Open1                   ;jump if error
  245.         mov     ax, desname             ;destination file
  246.         mov     bp, ax
  247.         mov     bx, di                  ;buffer record
  248.         mov     cl, BUFFER_CREATE       ;create
  249.         call    BufOpn                  ;open buffer
  250. Open1   ret
  251.         ENDP
  252.  
  253. ;========================================
  254. ; Close files.
  255. ;
  256. ; In: SI and DI= source and destination
  257. ;     buffer records.
  258. ;
  259. ; Out: CY= set if error; BP= name of file
  260. ;      if error.
  261.  
  262. Close   PROC    NEAR
  263.         mov     bp, desname     ;name of file if error
  264.         mov     bx, di
  265.         call    BufPut          ;flush destination buffer
  266.         jc      Close1
  267.         mov     bx, di
  268.         call    BufClo          ;close destination buffer
  269.         mov     bx, si
  270.         call    BufClo          ;close source buffer
  271.         clc
  272. Close1  ret
  273.         ENDP
  274.  
  275. ;========================================
  276. ; Process files.
  277. ;
  278. ; In: SI and DI= buffer record addresses.
  279. ;
  280. ; Out: CY= set if error; BP= name of file
  281. ;      if error.
  282.  
  283. Process PROC    NEAR
  284.         sub     bp, bp          ;zero column
  285.         jmps    Proces7
  286.  
  287. ;--- end of file or error reading
  288.  
  289. Proces1 or      al, al          ;check if really error
  290.         jnz     Proces4         ;jump if so
  291.  
  292. Proces2 cmp     lincnt, 0       ;check if any saved lines
  293.         je      Proces3
  294.         mov     lincnt, 1       ;write one line
  295.         mov     tabcnt, 0       ;zero tab count
  296.         mov     spccnt, 0       ;zero space count
  297. Proces3 call    Write           ;write
  298.         jc      Proces5
  299.         mov     al, EOF         ;end of file
  300.         mov     bx, di          ;buffer record
  301.         call    PutByt          ;write byte
  302.         jc      Proces5
  303.         clc
  304.         ret
  305.  
  306. ;--- error reading
  307.  
  308. Proces4 mov     bp, srcname
  309.         stc
  310.         ret
  311.  
  312. ;--- error writing
  313.  
  314. Proces5 mov     bp, desname
  315.         stc
  316.         ret
  317.  
  318. ;--- found space
  319.  
  320. Proces6 Check                   ;check if tab
  321.         inc     spccnt          ;increment spaces
  322.         inc     bp              ;increment column
  323.  
  324. ;=== main processing loop
  325.  
  326. Proces7 mov     bx, si
  327.         call    GetByt          ;read a byte
  328.         jc      Proces1
  329.         cmp     al, ' '         ;check if space
  330.         je      Proces6
  331.         cmp     al, TAB         ;check if tab
  332.         je      Proces9
  333.         cmp     al, CR          ;check if carriage return
  334.         je      Proces7
  335.         cmp     al, LF          ;check if linefeed
  336.         je      ProcesB
  337.         cmp     al, EOF         ;check if end of file
  338.         je      Proces2
  339.  
  340. ;--- found text character
  341.  
  342.         Check                   ;check if tab
  343.         inc     bp              ;increment column
  344.  
  345.         mov     dx, spccnt      ;space count
  346.         or      dx, tabcnt      ;or tab count
  347.         or      dx, lincnt      ;or line count
  348.         jnz     ProcesC         ;jump if any set
  349.  
  350. Proces8 mov     bx, di
  351.         call    PutByt          ;write character
  352.         jnc     Proces7         ;loop back if no error
  353.         jmps    Proces5
  354.  
  355. ;--- found tab
  356.  
  357. Proces9 mov     cx, bp          ;load column
  358.         and     cx, 111B        ;mask odd space bits
  359.         sub     cx, 8           ;spaces in tab
  360.         neg     cx              ;adjust
  361.  
  362. ProcesA Check                   ;check if tab
  363.         inc     spccnt          ;increment spaces
  364.         inc     bp              ;increment column
  365.         loop    ProcesA         ;loop for each space
  366.         jmp     Proces7
  367.  
  368. ;--- found linefeed
  369.  
  370. ProcesB inc     lincnt          ;increment line count
  371.         mov     tabcnt, 0       ;zero tab count
  372.         mov     spccnt, 0       ;zero space count
  373.         sub     bp, bp          ;zero column number
  374.         jmp     Proces7
  375.  
  376. ;--- stored characters before a text character
  377.  
  378. ProcesC push    ax
  379.         call    Write           ;write stored stuff
  380.         pop     ax
  381.         jnc     Proces8         ;jump back if okay
  382.         jmp     Proces5
  383.         ENDP
  384.  
  385. ;========================================
  386. ; Check if should output tab.
  387.  
  388. Check   MACRO
  389.         test    flags, NO_COMP  ;check if no compress
  390.         jnz     Check1          ;jump if so
  391.         cmp     spccnt, 0       ;check if any stored spaces
  392.         jz      Check1          ;jump if not
  393.         test    bp, 111B        ;check if at tab stop
  394.         jnz     Check1          ;jump if not
  395.         inc     tabcnt          ;increment tabs
  396.         mov     spccnt, 0       ;reset space count
  397. Check1
  398.         ENDM
  399.  
  400. ;========================================
  401. ; Write saved stuff.
  402.  
  403. Write   PROC NEAR
  404.  
  405. ;--- store saved lines
  406.  
  407.         cmp     lincnt, 0       ;check if any lines
  408.         je      Write2          ;skip if not
  409. Write1  mov     al, CR          ;carriage return
  410.         mov     bx, di          ;buffer record
  411.         call    PutByt          ;write byte
  412.         jc      Write7          ;jump if error
  413.         mov     al, LF          ;linefeed
  414.         mov     bx, di          ;buffer record
  415.         call    PutByt          ;write byte
  416.         jc      Write7          ;jump if error
  417.         dec     lincnt          ;decrement line count
  418.         jnz     Write1          ;loop back if more
  419.  
  420. ;--- store saved tabs
  421.  
  422. Write2  cmp     tabcnt, 0       ;check if any tabs
  423.         je      Write4          ;skip if not
  424. Write3  mov     al, TAB         ;tab character
  425.         mov     bx, di          ;buffer record
  426.         call    PutByt          ;write byte
  427.         jc      Write7          ;jump if error
  428.         dec     tabcnt          ;decrement count
  429.         jnz     Write3          ;loop back if more
  430.  
  431. ;--- store saved spaces
  432.  
  433. Write4  cmp     spccnt, 0       ;check if any spaces
  434.         je      Write6          ;skip if not
  435. Write5  mov     al, ' '         ;space character
  436.         mov     bx, di          ;buffer record
  437.         call    PutByt          ;write byte
  438.         jc      Write7          ;jump if error
  439.         dec     spccnt          ;decrement count
  440.         jnz     Write5          ;loop back if more
  441. Write6  clc
  442. Write7  ret
  443.         ENDP
  444.  
  445. ;========================================
  446. ; Data.
  447.  
  448. spccnt  DW      0       ;space count
  449. tabcnt  DW      0       ;tab count
  450. lincnt  DW      0       ;line end count
  451.  
  452. ;--- flags
  453.  
  454. NO_COMP EQU     1B      ;don't compress spaces
  455. DO_REN  EQU     10B     ;rename output file and delete input file
  456.  
  457. flags           DB      0
  458.  
  459. ;--- text
  460.  
  461. opt_com DB      '/C',0
  462. opt_exp DB      '/X',0
  463. exten   DB      '.$$$',0
  464.  
  465. banner  DB      13,10,'TABS  Version 1.00  Eric Tauck  2/20/90',0
  466. emess1  DB      13,10,'Not enough memory for buffers',0
  467. emess2  DB      13,10,'Could not open or create file: ',0
  468. emess3  DB      13,10,'Error reading or writing file: ',0
  469.  
  470. help    DB      13,10
  471.         DB      'Usage: TABS source [target] [/C] [/X]',13,10
  472.         DB      13,10
  473.         DB      '  /C  compresses spaces to tabs',13,10
  474.         DB      '  /X  expands tabs to spaces'
  475.         DB      0
  476.  
  477. ;--- file names
  478.  
  479. srcname DW      0FFFFH          ;address of source file
  480. desname DW      0FFFFH          ;address of destination file name
  481.  
  482. ;--- uninitialized file data
  483.  
  484. srcfile LABEL   BYTE                    ;source file record
  485.         ORG     +BUFFER_RECORD
  486. desfile LABEL   BYTE                    ;destination file record
  487.         ORG     +BUFFER_RECORD
  488. desfnam LABEL   WORD                    ;destination name if none specified
  489.         ORG     +129
  490.